package app.frequentpatterns.fpgrowth;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Random;

import app.Main.ProcessFile;

/**
 * This class represents a binary context (transaction database). It can read
 * the context directly from a file. See the ca.pfv.spmf.test folder for some
 * examples of files containing binary contexts.
 * 
 * @author Philippe Fournier-Viger
 */
public class Database {

	// Context
	private final List<Itemset> objects = new ArrayList<Itemset>();
	public final Map<Integer, Double> mapWeight = new HashMap<Integer, Double>();
	public final Map<Integer, Integer> mapSupport = new HashMap<Integer, Integer>();
	public int numOfItem = 0;
	public boolean printAble = true;
	public void addItemset(Itemset itemset) {
		objects.add(itemset);
		// attributes.addAll(itemset.getItems());
	}

	public void loadFile(String path) throws IOException {
		String thisLine;
		BufferedReader myInput = null;
		try {
			FileInputStream fin = new FileInputStream(new File(path));
			myInput = new BufferedReader(new InputStreamReader(fin));
			while ((thisLine = myInput.readLine()) != null) {
				if (thisLine.charAt(0) != '#') {
					String[] itemset = thisLine.split(" ");
					addObject(itemset);
					for (String item : itemset) {
						int intItem = Integer.parseInt(item);
						if (mapSupport.get(intItem) == null) {
							mapSupport.put(intItem, 1);
						} else {
							mapSupport.put(intItem,
									mapSupport.get(intItem) + 1);
						}
					}
				}
			}

		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (myInput != null) {
				myInput.close();
			}
		}
	}

	public void addObject(String attributs[]) {
		// We assume that there is no empty line
		Itemset itemset = new Itemset();
		for (String attribute : attributs) {
			if ("".equals(attribute)) {
				continue;
			}
			Integer item = new Integer(Integer.parseInt(attribute));
			itemset.addItem(item);
			// attributes.add(item);
		}
		objects.add(itemset);
	}

	public void printContext() {
		System.out
				.println("===================  BINARY CONTEXT ===================");
		int count = 0;
		for (Itemset itemset : objects) { // pour chaque objet
			System.out.print("0" + count + ":  ");
			itemset.print();
			System.out.println("");
			count++;
		}
	}

	public void printContextWeight() {
		System.out
				.println("===================  WEIGHT CONTEXT ===================");
		int count=0;
		//Map<Integer, Integer> map = new HashMap<Integer, Integer>();
		for (Map.Entry<Integer, Double> entry : mapWeight.entrySet()) {
		    System.out.println(++count+". Weight of Item " + entry.getKey() + " is = " + entry.getValue());
		}
	}

	public int size() {
		return objects.size();
	}

	public List<Itemset> getObjects() {
		return objects;
	}

	public void loadWeightFile1(String path) throws IOException {
		//load weight file with key:value pair
		String thisLine;
		BufferedReader myInput = null;
		int key=0;
		double value=0.0;
		try {
			FileInputStream fin = new FileInputStream(new File(path));
			myInput = new BufferedReader(new InputStreamReader(fin));
			while ((thisLine = myInput.readLine()) != null) {
				if (thisLine.charAt(0) != '#') {
					//find the delimiter in line 
					int demiliterPosition = thisLine.indexOf(':', 1);
					//Key is on the left of delimiter
					key = Integer.parseInt(thisLine.substring(0,demiliterPosition));
					//and value is on the right 
					value = Double.parseDouble(thisLine.substring(demiliterPosition+1,thisLine.length()));
					mapWeight.put(key,value);
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (myInput != null) {
				myInput.close();
			}
		}
	}
	public void loadWeightFile(String path) throws IOException {
		//load weight file with default key increase from 1
		String thisLine;
		BufferedReader myInput = null;
		int key=0;
		try {
			FileInputStream fin = new FileInputStream(new File(path));
			myInput = new BufferedReader(new InputStreamReader(fin));
			while ((thisLine = myInput.readLine()) != null) {
				if (thisLine.charAt(0) != '#') {
					mapWeight.put(++key,Double.parseDouble(thisLine.toString()));
				}
			}
		} catch (Exception e) {
			e.printStackTrace();
		} finally {
			if (myInput != null) {
				myInput.close();
			}
		}
	}
	public void createRandomWeightRange(double randomMin,
		double randomMax) {
		if (mapSupport.isEmpty()){
			throw new NullPointerException("Data must be loaded first!"); 
		}
		ProcessFile fileWriter = new ProcessFile();
		String path = "D:\\My Books\\My Document\\Test Data";   
        String nameOfFile ="weightForConnect";
        File file = new File(path,nameOfFile);
        
		for (Integer key:mapSupport.keySet()){
        //for (Integer key=1;key<1000;key++){
			Double ranWeight = randomize(randomMin,randomMax);
			mapWeight.put(key, ranWeight);
			fileWriter.writeAppend(file,key+":"+ranWeight.toString());
		}
	}
	private Double randomize(double randomMin, double randomMax) {
		if ( randomMin > randomMax ) {
		      throw new IllegalArgumentException("RandomMin cannot exceed randomMax!");
		}
		Random randomnumber = new Random();
		return roundTwoDecimals (randomMin+ randomnumber.nextDouble()*(randomMax-randomMin));
	}

	protected double roundTwoDecimals(double d) {
		return Math.round(d*100)/100.0d;
	}
}
